home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
pctj8411.arc
/
DIV_F.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-01-18
|
6KB
|
128 lines
;*************************************************************
; FLOATING POINT
; DIVISION ROUTINE
;*************************************************************
DIV_F PROC NEAR
PUSH SI ;save index registers
PUSH DI
; divide by zero?
MOV DX,[SI] ;get op2 (divisor) in CX:DX
MOV CX,[SI]+2
MOV BX,10 ;set error flag
MOV AX,DX ;is op2 zero?
OR AX,CX
JNZ D1 ;if zero, quit with BX=10
JMP EXIT
; compute result sign
D1: MOV AL,CL ;OP1 high byte in AL
XOR AL,[DI]+2 ;XOR with OP2 high byte
AND AX,0080H ;isolate sign bit
PUSH AX ;save it
; compute exponent
SUB AX,AX
MOV BX,AX
MOV AL,CH ;E2 in AX
MOV BL,[DI]+3 ;E1 in BX
SUB AX,128 ;remove bias
SUB BX,AX ;E1-E2
INC BX ;add 1 since shift right later
;
CMP BX,255 ;overflow if
JLE D3 ;E>255
JMP D13
;
D3: CMP BX,0 ;underflow if
JGE D5 ;E<0
JMP D14
; compute 1-(OP2LO/OP2HI)/2^16
D5: PUSH BX ;save E in BL
SUB AX,AX
MOV BH,CL ;OP2HI in BX
MOV BL,DH
OR BH,10000000B ;restore leading 1
MOV DH,DL ;OP2LO in DX
MOV DL,AL
OR DX,DX ;if OP2LO is zero
JNZ D6
XCHG BX,AX ;put OP2HI in AX
MOV SI,BX ;set result in BX:SI to zero
JMP SHORT D8 ;and skip this step
; compute OP2LO/OP2HI first
D6: SUB CX,CX
CMP DX,BX ;if OP2LO>=OP2HI, quotient>=1
JB D7
SUB DX,BX ;subtract OP2HI to prevent overflow
MOV CX,1 ;save quotient 1 or 0 in CX
;
D7: DIV BX ;OP2LO/OP2HI now in CX:AX
;
PUSH CX ;save OP2LO/OP2HI
PUSH AX
SUB AX,AX ;divide remainder in DX:AX
DIV BX
POP DX
POP CX ;OP2LO/OP2HI in CX:DX:AX
; subtract it from 1
PUSH DI ;save DI & OP2HI
PUSH BX
SUB DI,DI ;clear registers
MOV SI,DI
MOV BX,DI
SUB DI,AX
SBB SI,DX
SBB BX,CX
POP AX ;retrieve OP2HI & DI
POP DI
; compute OP1/OP2HI
D8: PUSH BX ;save 1-OP1LO/OP2HI
PUSH SI
MOV BX,AX ;OP2HI in BX
SUB AX,AX ;clear AX & SI
MOV SI,AX
MOV DX,[DI]+1 ;OP1 in DX:AX
OR DH,10000000B ;restore leading 1
MOV AH,[DI]
;
CMP DX,BX ;if OP1>=OP2HI
JB D9
SUB DX,BX ;subtract OP2HI to prevent overflow
INC SI ;and save quotient of one in SI
;
D9: DIV BX ;divide OP1/OP2HI
MOV CX,AX ;save quotient in CX
SUB AX,AX
DIV BX ;divide remainder in DX
MOV DX,CX ;OP1/OP2HI now in SI:DX:AX
SHR SI,1 ;shift it right
RCR DX,1
RCR AX,1 ;now in DX:AX
; compute (OP1/OP2HI)*(OP2LO/OP2HI)/2^16
POP BX ;1-OP2LO/OP2H9)/2^16 in CX:BX
POP CX
MOV SI,BX ;if OP2LP/OP2HI was zero
OR SI,CX ;product is OP1/OP2HI
JZ D10 ;so no need to multiply
CALL MUL32 ;do the multiplication
; normalize
D10: POP BX ;get exponent in BX
D11: OR DX,DX
JS D12 ;if sign bit off
SHL CX,1 ;shift it left
RCL AX,1
RCL DX,1
DEC BX ;decrement exponent
JMP D11 ;see if normalized
; reformat for output
D12: MOV BH,BL ;exponent in BH
XCHG AH,AL ;move trailing bits up to DH
XCHG DL,AH ;4 byte mantissa in DL:AX:DH
XCHG DH,DL
SUB CX,CX
POP DI ;result sign in DI
JMP R0 ;ROUND in addition routine
;
D13: POP DI ;get sign in DI
JMP OVER_F
D14: POP AX ;remove sign from stack
JMP UNDER_F
DIV_F ENDP